package org.openzip.jarsfx.unpacking.view.swing;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.zip.ZipEntry;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import org.openzip.jarsfx.unpacking.model.IOpenZipUnpacker;
import org.openzip.jarsfx.unpacking.view.IUnpackerUI;
import org.openzip.jarsfx.unpacking.view.MyJarFile;
import org.openzip.jarsfx.unpacking.view.swing.util.StandardForm;

/**
 * This is an implementation of <code>IUnpackerUI</code> interface.<br>
 * It provides a graphical user interface for the unpacking logic. For seeing
 * how the GUI looks like, refer to the specification.
 * 
 * @author Jakub Závěrka
 */
public class UnpackerGUI implements IUnpackerUI
{
	//logic
	private IOpenZipUnpacker logic;
	//main window and its content pane
	private JFrame mainWindow;
	private JComponent contentPane;
	//file panel for the destination choosing
	private UnpackFilePanel filePanel;
	private Container centerPanel;
	//file tree
	//private CheckboxedTree fileTree;
	private JButton selectAllButton;
	private JButton deselectAllButton;
	private JButton closeButton;
	private JButton unpackButton;
	private JButton moreLessButton;
	
	//selection model
	//private SelectedFilesModel selectionModel;
	
	private Dimension preferredButtonSize = new Dimension(100, 25);
	
	/**
	 * Constructor of the GUI. Should be called only once.
	 * @param treeRoot Root file for the file tree.
	 */
	public UnpackerGUI(/*File treeRoot*/){
		prepareMainWindow();
		filePanel = new UnpackFilePanel();
		filePanel.getJComponent().setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
		StandardForm form = new StandardForm(filePanel.getJComponent(), 
					centerPanel = prepareMiddlePanel(/*treeRoot*/), prepareBottomPanel());
		form.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		mainWindow.setContentPane(contentPane = form.getJComponent());
		mainWindow.pack();
		mainWindow.setLocationRelativeTo(null);
		
		//selectAllNodes(true);
	}

	/**
	 * Prepares the middle panel (file tree and select/deselect all buttons).
	 * @param treeRoot Root file for the file tree.
	 * @return Prepared component.
	 */
	private Container prepareMiddlePanel(/*File treeRoot*/){
		/*fileTree = new CheckboxedTree(treeRoot, false);
		fileTree.setRootVisible(false);
		selectionModel = new SelectedFilesModel();
		fileTree.setGlobalSelectionModel(selectionModel);*/
		
		selectAllButton = new JButton("Select all");
		selectAllButton.setPreferredSize(preferredButtonSize);
		selectAllButton.addActionListener(new SelectAllListener());
		deselectAllButton = new JButton("Deselect all");
		deselectAllButton.setPreferredSize(preferredButtonSize);
		deselectAllButton.addActionListener(new DeselectAllListener());
		
		JPanel panel = new JPanel(new BorderLayout(5, 0));
			JPanel treePanel = new JPanel(new BorderLayout());
			treePanel.add(new JLabel("Files to unpack:"), BorderLayout.NORTH);
			//treePanel.add(new JScrollPane(fileTree));
		panel.add(treePanel);
			Box buttonPanel = new Box(BoxLayout.Y_AXIS);
			buttonPanel.add(Box.createRigidArea(new Dimension(0, 20)));
			buttonPanel.add(selectAllButton);
			buttonPanel.add(Box.createRigidArea(new Dimension(0, 10)));
			buttonPanel.add(deselectAllButton);
		panel.add(buttonPanel, BorderLayout.EAST);

		panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
		panel.setVisible(false);
		return panel;			
	}

	/**
	 * Prepares the bottom panes (panel with More/less, Unpack and Close 
	 * buttons).
	 * @return Prepared component.
	 */
	private Component prepareBottomPanel(){
		closeButton = new JButton("Close");
		
		closeButton.addActionListener(new CloseButtonListener());
		
		unpackButton = new JButton("Unpack all");
		unpackButton.addActionListener(new UnpackListener());
		
		moreLessButton = new JButton("More >");
		moreLessButton.addActionListener(new MoreLessListener());
		moreLessButton.setVisible(false);
		
		JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		panel.add(moreLessButton);
		panel.add(Box.createRigidArea(new Dimension(5, 0)));
		panel.add(closeButton);
		panel.add(Box.createRigidArea(new Dimension(5, 0)));
		panel.add(unpackButton);

		panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
		
		return panel;
	}
	
	/**
	 * Prepares the main window.
	 */
	private void prepareMainWindow(){
		mainWindow = new JFrame("OPEN Zip - Unpack");
		mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override public void showGui(IOpenZipUnpacker logic){
		this.logic = logic;
		mainWindow.setVisible(true);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override public void showGui(IOpenZipUnpacker logic, 
				Collection<ZipEntry> files){
		throw new UnsupportedOperationException(
					"This functionality is not implemented");
	}
	
	/**
	 * This method (de)select all nodes in the file tree.
	 * @param selected <code>true</code> to select all nodes, <code>false</code>
	 * to deselect all nodes.
	 */
	private void selectAllNodes(boolean selected){
		/*FileTreeNode root = (FileTreeNode)fileTree.getModel().getRoot();
		Enumeration enumeration = root.children();
		while(enumeration.hasMoreElements()){
			FileTreeNode fileNode = (FileTreeNode)enumeration.nextElement();
			fileNode.getFileCheckBox().setSelected(selected);
			fileTree.repaint();
		}*/
	}

	/**
	 * Listener for the Close button.
	 */
	private class CloseButtonListener implements ActionListener
	{
		/**
		 * Displays a confirmation message and terminates the program.
		 */
		public void actionPerformed(ActionEvent arg0){
			/*String message = "Are you sure you want to quit and forget"
									+ " all your selected files?";
			int userChoice = JOptionPane.showOptionDialog(mainWindow, message, 
									"Confimation",
									JOptionPane.YES_NO_OPTION,
									JOptionPane.QUESTION_MESSAGE, null, null,
									JOptionPane.INITIAL_VALUE_PROPERTY);
			if(userChoice == JOptionPane.YES_OPTION){*/
				System.exit(0);
			//}
		}
	}

	/**
	 * Listener for the More/Less button.
	 * @author Jakub
	 *
	 */
	private class MoreLessListener implements ActionListener
	{
		/**
		 * If the tree is not displayed, displays it and changes text to "Less".
		 * If the tree is displayed, hides it and changes text to "More".
		 */
		public void actionPerformed(ActionEvent arg0) {
			boolean willDisplay = !centerPanel.isVisible();
			moreLessButton.setText(willDisplay ? "Less <" : "More >");
			centerPanel.setVisible(willDisplay);
			contentPane.revalidate();
			mainWindow.pack();
			mainWindow.setLocationRelativeTo(null);
		}
	}
	
	/**
	 * Listener for the Unpack button.
	 */
	private class UnpackListener implements ActionListener
	{
		/**
		 * Passes the selected files to the unpacking logic.
		 */
		@Override public void actionPerformed(ActionEvent e){
			Collection<ZipEntry> jarFiles = new ArrayList<ZipEntry>();
			/*for(File f : selectionModel){
				jarFiles.add(((MyJarFile)f).getEntry());
			}*/
			logic.unpack(filePanel.getFile(), jarFiles);
			JOptionPane.showMessageDialog(mainWindow, 
						"All files have been unpacked.", "Completed", 
						JOptionPane.INFORMATION_MESSAGE);
		}
	}
	
	/**
	 * Listener for the Select all button.
	 */
	private class SelectAllListener implements ActionListener
	{
		@Override public void actionPerformed(ActionEvent e){
			selectAllNodes(true);
		}
	}
	
	/**
	 * Listener for the Deselect all button.
	 */
	private class DeselectAllListener implements ActionListener
	{
		@Override public void actionPerformed(ActionEvent e){
			selectAllNodes(false);
		}
	}
}
